home *** CD-ROM | disk | FTP | other *** search
- Path: linus.mitre.org!spectre!eachus
- From: eachus@spectre.mitre.org (Robert I. Eachus)
- Newsgroups: comp.lang.ada,comp.lang.c++
- Subject: Iterators (was Re: some questions re. Ada/GNAT from a C++/GCC user)
- Date: 30 Mar 1996 00:11:46 GMT
- Organization: The Mitre Corp., Bedford, MA.
- Message-ID: <EACHUS.96Mar29191146@spectre.mitre.org>
- References: <wnewmanDoxrCp.DKv@netcom.com> <Dp1oAw.7Cz@world.std.com>
- NNTP-Posting-Host: spectre.mitre.org
- In-reply-to: bobduff@world.std.com's message of Fri, 29 Mar 1996 19:47:20 GMT
-
- In article <Dp1oAw.7Cz@world.std.com> bobduff@world.std.com (Robert A Duff) writes:
-
- > > Is there any way in Ada to iterate abstractly over the contents of a
- > > container,...
-
- > Several ways:
-
- > - Write a generic procedure Iterate, which takes a formal
- > procedure representing the body of the loop -- that is,
- > the formal procedure says what to do for each element.
-
- Funny you should mention it... Right now I have two projects where
- I am dealing with a large mass (1000s) of source files. I need to run
- some tools over the code. The choice was between Ada and a shell
- script...I chose Ada:
-
- generic
- with procedure To_Do(File: in String);
- procedure Iterate_Files(Pattern: in String := "*";
- Directory: in String := "");
- -- This generic iterates over all files in a directory matching Pattern and
- -- calls To_Do once for each such directory entry. If a file has several
- -- links in the directory To_Do will be called once for each.
-
- (The body for SunAda/VADS is tacked on at the end of this
- message. It isn't all that complex. If someone wants to rewrite for
- GNAT and post, feel free, but there may be a lot of GNAT versions
- needed, I don't know if it is possible to share code between
- different operating systems.)
-
- Two observations. First, the generic procedure approach is
- certainly right for this case. Second, the VADS run-time provided a
- call for freeing A_Strings, but not for find_files.find_file_rec, so I
- put in the call for the A_Strings case only. If I felt that there
- would be hundreds of calls with different patterns, I probably would
- have gone through the pain of "fixing" the find_files package by
- adding the missing functionality. But in my case, the one call to
- A_Strings.Free(Next) is enough garbage collection for all practical
- purposes...the call in the exception handler is for style more than
- anything else.
-
- And I know that this is something I have said before, but this
- particular example is a good one. The primary argument in favor of
- compilers which support general garbage collection is that the end
- user shouldn't have to worry about garbage collection. But in this
- example 1) the user of the package sees no garbage ever and 2)
- managing memory "right" was an extremely small effort when writing the
- generic. Even if all Ada compilers had generalized garbage
- collectors, the right choice here would be to build a procedure which
- predictably cleaned up after itself rather than warning the user that
- there would be lots of garbage generated which might affect global
- performance.
-
-
- Robert I. Eachus
-
- with Standard_Disclaimer;
- use Standard_Disclaimer;
- function Message (Text: in Clever_Ideas) return Better_Ideas is...
-
-
- ----------------------------------------------------------------------------
- -- generic
- -- with procedure To_Do(File: in String);
- with A_Strings;
- with File_Names;
- procedure Iterate_Files(Pattern: in String := "*";
- Directory: in String := "") is
- Pat: A_Strings.A_String;
- Handle: File_Names.Find_File_Info;
- Next: A_Strings.A_String;
- begin
-
- if Directory = ""
- then Pat := A_Strings.To_A(Pattern);
- else Pat := A_Strings.To_A(Directory & "/" & Pattern);
- end if;
-
- Handle := File_Names.Init_Find_File(Pat);
- loop
- Next := File_Names.Find_File(Handle);
- if Directory = "" and then Next.s(1..2) = "./"
- then To_Do(Next.s(3..Next.len));
- else To_Do(Next.s);
- end if;
- A_Strings.Free(Next);
- end loop;
- exception
- when File_Names.No_More_Files => A_Strings.Free(Pat);
- end Iterate_Files;
-
- -----------------------------------------------------------------------------
- --
-
- Robert I. Eachus
-
- with Standard_Disclaimer;
- use Standard_Disclaimer;
- function Message (Text: in Clever_Ideas) return Better_Ideas is...
-